package easyjava.function;

import java.util.Iterator;

/**
 * 生成器创建方法
 *
 */
public interface GenerateFunction {

    @FunctionalInterface
    interface GenerateFun {
        Object create(int i);
    }

    @FunctionalInterface
    interface Generator<T> extends Iterable<T>, Iterator<T> {
        T call();

        @Override
        default boolean hasNext() {
            return true;
        }

        @Override
        default T next() {
            return this.call();
        }

        @Override
        default Iterator<T> iterator() {
            return this;
        }
        
        default String toStr() {
        	StringBuilder strBuilder=new StringBuilder();
        	strBuilder.append('(');
        	while(hasNext()) {
        		strBuilder.append(call()).append(',');
        	}
        	if(strBuilder.length()>1) {
        		return strBuilder.substring(0,strBuilder.length()-1)+")";
        	}
        	strBuilder.append(')');
        	return strBuilder.toString();
        }
    }

    static <T> Generator<T> generator(final GenerateFun generateFun) {
        return new Generator<T>() {
        	
        	private int indexPointer = 0;
        	
        	@Override
            public Iterator<T> iterator() {
        		indexPointer = 0;
            	return Generator.super.iterator();
        	}
        	
        	@Override
            public T call() {
        		T returnVal = (T) generateFun.create(indexPointer);
        		indexPointer++;
                return returnVal;
        	}
        	
        	@Override
        	public String toString() {
        		return toStr();
        	}
        };
    }
    
    static <T> Generator<T> generator(final GenerateFun generateFun,int end) {
        return generator(generateFun,0,end);
    }

    static <T> Generator<T> generator(final GenerateFun generateFun,int start,int end) {
        return generator(generateFun,start,end,1);
    }

    static <T> Generator<T> generator(final GenerateFun generateFun,int start,int end,int step) {
        return new Generator<T>() {

        	private int indexPointer = start;
        	
            @Override
            public boolean hasNext() {
            	boolean hasNextVal = true;
                if(end>=start){
                	hasNextVal=indexPointer<end;
                }else{
                	hasNextVal=indexPointer>end;
                }
                return hasNextVal;
            }

            @Override
            public Iterator<T> iterator() {
            	indexPointer = start;
            	return Generator.super.iterator();
            }
            
            @Override
            public T call() {
                T returnVal = (T) generateFun.create(indexPointer);
                indexPointer+=step;
                return returnVal;
            }
            
            @Override
        	public String toString() {
        		return toStr();
        	}
        };
    }
}
